using Microsoft.EntityFrameworkCore;
using net_work.Common.Request;
using net_work.Common.Result;
using net_work.Config;
using net_work.Data.DTO.Sys;
using net_work.Data.Entity.Sys;
using net_work.Data.VO.Sys;
using net_work.IRepository.Sys;

namespace net_work.Repository.Sys;

public class StudentRepository(ApplicationDbContext dbContext) : Repository<Student>(dbContext), IStudentRepository
{
    public async Task<long> InsertAsync(StudentAddRequest studentAddRequest)
    {
        var existingStudent =
            await dbContext.Students.IgnoreQueryFilters()
                .FirstOrDefaultAsync(s => s.StudentNumber == studentAddRequest.StudentNumber);
        if (existingStudent != null)
        {
            return -1;
        }

        var newStudent = new Student
        {
            StudentNumber = studentAddRequest.StudentNumber,
            StudentQualification = studentAddRequest.StudentQualification,
            AdmissionDate = studentAddRequest.AdmissionDate,
            GraduationDate = studentAddRequest.GraduationDate,
            EmergencyContactName = studentAddRequest.EmergencyContactName,
            EmergencyContactPhone = studentAddRequest.EmergencyContactPhone,
            ClassId = studentAddRequest.ClassId,
            PsnId = studentAddRequest.PersonId,
            Remark = studentAddRequest.Remark
        };
        await dbContext.Students.AddAsync(newStudent);
        await dbContext.SaveChangesAsync();
        return newStudent.Id;
    }

    public async Task<bool> UpdateAsync(StudentUpdateRequest studentUpdateRequest)
    {
        var students = await dbContext.Students
            .IgnoreQueryFilters()
            .Where(x => x.StudentNumber == studentUpdateRequest.StudentNumber || x.Id == studentUpdateRequest.Id)
            .ToListAsync();

        var conflictStudent = students.FirstOrDefault(x => x.Id != studentUpdateRequest.Id);
        if (conflictStudent != null)
        {
            return false;
        }

        var existingStudent = students.FirstOrDefault(x => x.Id == studentUpdateRequest.Id);
        if (existingStudent == null)
        {
            return false;
        }

        existingStudent.Remark = studentUpdateRequest.Remark;
        existingStudent.StudentNumber = studentUpdateRequest.StudentNumber;
        existingStudent.StudentQualification = studentUpdateRequest.StudentQualification;
        existingStudent.AdmissionDate = studentUpdateRequest.AdmissionDate;
        existingStudent.GraduationDate = studentUpdateRequest.GraduationDate;
        existingStudent.EmergencyContactName = studentUpdateRequest.EmergencyContactName;
        existingStudent.EmergencyContactPhone = studentUpdateRequest.EmergencyContactPhone;
        existingStudent.ClassId = studentUpdateRequest.ClassId;
        existingStudent.PsnId = studentUpdateRequest.PersonId;

        await dbContext.SaveChangesAsync();
        return true;
    }

    public async Task<PagedResult<StudentResult>> GetStudentPagedAsync(PagedRequest request)
    {
        var query = from student in dbContext.Students
            join person in dbContext.People on student.PsnId equals person.Id
            join user in dbContext.Users on person.Id equals user.PsnId
            join administrativeClass in dbContext.AdministrativeClasses on student.ClassId equals administrativeClass.Id
            join college in dbContext.Colleges on administrativeClass.CollegeId equals college.Id
            select new StudentResult
            {
                Id = student.Id,
                StudentNumber = student.StudentNumber,
                StudentQualification = student.StudentQualification,
                AdmissionDate = student.AdmissionDate,
                GraduationDate = student.GraduationDate,
                EmergencyContactName = student.EmergencyContactName,
                EmergencyContactPhone = student.EmergencyContactPhone,
                ClassId = student.ClassId,
                PsnId = student.PsnId,
                Remark = student.Remark,
                CreatedBy = student.CreatedBy,
                CreatedTime = student.CreatedTime,
                UpdatedBy = student.UpdatedBy,
                UpdatedTime = student.UpdatedTime,
                PsnName = person.PsnName,
                PsnGen = person.PsnGen,
                PsnIdType = person.PsnIdType,
                PsnIdNum = person.PsnIdNum,
                PsnNat = person.PsnNat,
                PsnRen = person.PsnRen,
                PsnAddr = person.PsnAddr,
                PsnBirDate = person.PsnBirDate,
                PsnBirAddr = person.PsnBirAddr,
                UserId = user.Id,
                UserEmail = user.UserEmail,
                UserPhone = user.UserPhone,
                UserAccount = user.UserAccount,
                UserPassword = user.UserPassword,
                UserRole = user.UserRole,
                ClassName = administrativeClass.ClassName,
                ColleId = college.Id,
                ColleName = college.ColleName
            };

        return await GetPagedQueryResultAsync(query, request);
    }
}